# -*- coding: utf-8 -*-

#    OriginDB
#    Copyright (C) 2010  Jason Power <power.jg@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


from PyQt4.QtGui import *
from PyQt4 import QtCore

from common import elementSymbols, elementColors

import openbabel

class Atom(QGraphicsItem):

	font = QFont("Verdana", 10)
	defaultStyleSheet = """
		sub {
			font-size:x-large;
		}
	"""

	def __init__(self, atom, parent=None):
		self.selected = False
		
		QGraphicsItem.__init__(self, parent)

		self.atom = atom
		self.symbolDoc = QTextDocument()
		self.symbolDoc.setDocumentMargin(0)
		self.symbolDoc.setDefaultStyleSheet(self.defaultStyleSheet)
		self.symbolDoc.setDefaultFont(self.font)
		#if self.atom.ImplicitHydrogenCount() > 0:
			#self.symbol += "H"+str(self.atom.ImplicitHydrogenCount())
		#print "Adding atom:", atom.GetIdx()

		self.forceShow = False
		self.forceForceShow = False

		self.rect = QtCore.QRectF()
		
		self.updatePos()

		self.hover = False

		self.setFlag(QGraphicsItem.ItemIsMovable, True)
		self.setFlag(QGraphicsItem.ItemIsSelectable, True)
		self.setAcceptHoverEvents(True)
		try:
			self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
		except AttributeError:
			pass #Need this in Qt4.6 not in Qt4.5

		self.updateSymbol()

		self.setZValue(10)

	def setSelected(self, selected):
		self.selected = selected
		self.update()

	def setAtomicNum(self, num):
		oldNum = self.atom.GetAtomicNum()
		self.atom.SetAtomicNum(num)
		self.atom.GetParent().UnsetImplicitValencePerceived()

		self.updateSymbol()
		self.update()
		return oldNum

	def setAtom(self, atom):
		self.atom = atom
		self.updateSymbol()

	def updateSymbol(self):
		symbol = elementSymbols[self.atom.GetAtomicNum()]
		color = elementColors[symbol]
		color = [i*255 for i in color]

		if self.atom.ImplicitHydrogenCount() > 0:
			bonds = 0
			for b in openbabel.OBAtomBondIter(self.atom):
				bonds += 1
			if bonds < 2:
				self.forceForceShow = True
			else:
				self.forceForceShow = False
				
			c = self.atom.ImplicitHydrogenCount()
			if c > 1:
				self.symbolDoc.setHtml("<span style=\"color:rgb(%i,%i,%i);\">%s</span>H<sub>%i</sub>" % (color[0], color[1], color[2], symbol, c))
			else:
				self.symbolDoc.setHtml("<span style=\"color:rgb(%i,%i,%i);\">%s</span>H" % (color[0], color[1], color[2], symbol))
		else:
			self.symbolDoc.setHtml("<span style=\"color:rgb(%i,%i,%i);\">%s</span>" % (color[0], color[1], color[2], symbol))

		self.computeBoundingRect()
			
		self.prepareGeometryChange()
		self.update()

	def updatePos(self):
		self.setPos(self.parentItem().translateFromAtomCoords([self.atom.GetX(), self.atom.GetY()]))

	def itemChange(self, change, value):
		if change == QGraphicsItem.ItemPositionHasChanged:
			value = value.toPointF()
			self.atom.SetVector(self.parentItem().translateToAtomCoords(value))
			self.parentItem().updateBonds(self.atom)
		return QGraphicsItem.itemChange(self, change, value)

	def hoverEnterEvent(self, event):
		self.forceShow = True
		self.updateSymbol()
		self.update()

	def hoverLeaveEvent(self, event):
		self.forceShow = False
		self.update()

	def computeBoundingRect(self):
		layout = self.symbolDoc.documentLayout()
		size = layout.documentSize()
		self.rect = QtCore.QRectF(-size.width()/2,-size.height()/2,size.width(),size.height())

	def boundingRect(self):
		return self.rect

	def paint(self, painter, option, widget):
		#print "drawing atom:", self.atom.GetIdx()

		if not self.forceShow and not self.forceForceShow and self.atom.IsCarbon() and not self.selected:
			return

		painter.setBrush(QBrush(QtCore.Qt.white))
		painter.setPen(QPen(QtCore.Qt.NoPen))
		r = self.boundingRect()
		m = max(r.width(), r.height())
		painter.drawEllipse(QtCore.QRectF(-m/2,-m/2,m,m))
		
		if self.selected:
			painter.setPen(self.parentItem().selectedPen)
			painter.drawRect(self.boundingRect())
		
		painter.translate(r.x(), r.y())
		self.symbolDoc.drawContents(painter)
		#painter.drawText(QtCore.QPointF(-self._fontMetrics.width(self.symbol)/2.0, self.fontHeight*.3), self.symbol)
